// @author caoshi
// @date 2022/11/29 15:00
// @since 1.0
// 基本数据类型指针的使用
package main

import "fmt"

func main() {
	// 1.定义整形变量a
	a := 10
	fmt.Println("a的数值是", a)
	fmt.Printf("a的数据类型是 %T\n", a)    // %T Printf打印数据类型
	fmt.Printf("a在内存中的地址是 %p\n", &a) // 0xc00000a0a8 打印变量a的内存地址

	// 2.创建一个指针变量用于存储变量a的地址
	var p1 *int
	fmt.Println(p1) // <nil> 空指针
	p1 = &a
	fmt.Println("p1的数值: ", p1)       // 0xc00000a0a8
	fmt.Printf("p1自己的地址: %p\n", &p1) //
	fmt.Println("p1指向的内存中存储的数值是:", *p1)

	// 3.操作变量,改变数值,并不会改变地址
	a = 100
	fmt.Println(a)
	fmt.Printf("a的地址%p\n", &a)

	// 4.通过指针修改数值
	*p1 = 200
	fmt.Println(a) // 200

	// 5.二级指针 --> 指向指针的指针
	var p2 **int
	fmt.Println(p2)                     // <nil>
	p2 = &p1                            // 将指针变量p1的地址赋值给p2
	fmt.Printf("%T,%T,%T\n", a, p1, p2) // int,*int,**int
	fmt.Println("p2的数值:", p2)
	fmt.Println("p2中存储的地址,对应的数值就是p1的地址,对应数据: ", *p2) // 0xc00000a0a8 实际就是a的地址
	fmt.Println("p2中存储的地址,对应的数值,再获取对应的数值: ", **p2)   // 200 就是a的值
}
